import axios from 'axios'
import store from '@/store'

import { history } from '@/router/history'
import { Toast } from 'antd-mobile'
import { isAuth } from './auth'
import { changeToken } from '@/store/modules/login'


const request = axios.create({
  baseURL: 'http://toutiao.itheima.net/v1_0',
  // baseURL: process.env.REACT_APP_URL
})

// 请求拦截器
request.interceptors.request.use((config) => {
  // 获取token
  const {
    login: { token },
  } = store.getState()

  // 除了登录请求外，其他请求统一添加 token
  if (token.token) {
    // ts中！操作符叫非空断言=》去掉null undefined 告诉ts类型是安全的
    config.headers!.Authorization = `Bearer ${token.token}`
  }

  return config
})

// 响应拦截器
request.interceptors.response.use(
  (res) => {
    // 简化返回数据
    return res.data
  },
  async (error) => {
    // 处理token过期/统一处理接口请求错误
    if (error.response.status === 401) {
      // 方式一：401直接跳回登录页=》重新登陆
      // Toast.show({
      //   content: '没有登录或token过期了',
      //   icon: 'fail',
      //   afterClose: () => {
      //     // 删除token
      //     //  store.dispatch(logout())
      //     history.replace('/login',
      //       { from: history.location.pathname },
      //     )
      //   },
      // })

      /**
       * 方式二：无感刷新token
         1. 401情况，使用 try-catch 处理异常，捕获异常时，清除本地 token和清空 redux token，提示消息并跳转到登录页面，最后抛出错误
         2. 判断是否登录：
           1. 没有登录：直接抛出异常，无需刷新
           2. 登录过：使用 `refresh_token` 通过默认的 **axios 发送请求**，**换取新的 token**
  
         3. 将新获取到的 token 存储到本地缓存中和 redux 中
         4. 使用封装的axios**继续发送原来的请求**
       */
      try {

        if (!isAuth()) {
          // 没有登录：直接抛出异常
          throw new Error('请登录！')
        }

        // 登录过：使用 refresh_token 换取新token
        // 1.获取refresh_token
        const { token: { refresh_token } } = store.getState().login
        // 2.调用后台接口，获取新token
        const res = await axios.put('http://toutiao.itheima.net/v1_0/authorizations', null, {
          headers: {
            Authorization: `Bearer ${refresh_token}`
          }
        })
        console.log(res.data.data.token)
        // 3.将获取到的token，更新redux和本地的token
        const newToken = {
          token: res.data.data.token,
          refresh_token
        }
        store.dispatch(changeToken(newToken))
        // 4.把原来401的请求，重新发送一次
        // error.config 上次401请求的配置（url、method、参数等）
        // 注意：重新发送的请求，一定要return，不然页面拿不到数据
        return request(error.config)

      } catch (error) {
        // 没有登录，抛出异常，会被捕获到错误，进行登录
        Toast.show({
          content: '没有登录或refresh_token过期了',
          icon: 'fail',
          afterClose: () => {
            // 删除token
            //  store.dispatch(logout())
            history.replace('/login',
              { from: history.location.pathname },
            )
          },
        })
      }
    }
    return Promise.reject(error)
  }
)

export default request